package com.fzrskj.cloud.free.core.tool;

import com.fzrskj.cloud.free.common.bean.ValidResult;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.*;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings("unused")
public class CVerificationTool {
	//配置文件路径
	private final static String JSONPATH = "/config/jsonParameter.json";
	private static JSONObject jsonObjectParm;
	public static String errorStr;
	public static int errorCode = -1;
	public static String errorNode;
	public static String errorType;
	private final static String VFT_ERROR_INIT = "初始化错误";
	private final static String VFT_ERROR_ARGS_INIT = "传入参数错误";
	private final static String VFT_ERROR_KEY = "CVERROR";
	private final static String VFT_ERROR_FILECFG = "读取配置文件错误";
	private final static String VFT_ERROR_FILECFGNOFIND = "找不到配置文件";
	private final static String VFT_ERROR_FILECFGFORMAT = "配置文件格式错误";
	private final static String VFT_ERROR_NOTNULL = "不能为空";
	private final static String VFT_ERROR_LENGTH = "长度错误";
	private final static String VFT_ERROR_TYPE = "类型错误";
	private final static String VFT_ERROR_PREG = "匹配失败";
	private final static String VFT_ERROR_NOMODE = "没有对应的模型";
	private final static String VFT_ERROR_SUCCESS = "验证成功";
	private final static String VFT_ERROR_METHOD = "验证方法失败";
	private final static String VFT_ERROR_SPACE = "";

	public static String getErrorNode() {
		return errorNode;
	}
	public static void setErrorNode(String errorNodeIn) {
		errorNode = errorNodeIn;
	}
	public static String getErrorType() {
		return errorType;
	}
	public static void setErrorType(String errorTypeIn) {
		errorType = errorTypeIn;
	}

	public static String getErrorStr() {
		return errorStr;
	}
	public static void setErrorStr(String errorStrIn) {
		errorStr = errorStrIn;
	}
	public static int getErrorCode() {
		return errorCode;
	}
	public static void setErrorCode(int errorCodeIn) {
		errorCode = errorCodeIn;
	}

	/**
	 * 设置错误输出
	 * ... 任意参数 必须是String
	 * @param args
	 */
	public static void setError(Object... args){
		StringBuilder fileStr = new StringBuilder("");
		int i = 0;
		for(Object value : args){
			if(i == 0){
				setErrorNode(value.toString());
			}else if(i == 1){
				setErrorType(value.toString());
				if(args.length > 2 && !args[2].equals("")){
					i++;
					continue;
				}
			}
			fileStr.append(value+" ");
            i++;
        }
		setErrorStr(fileStr.toString());
	}

	/**
	 * 局部错误输出
	 * @param args ... 任意参数 必须是String
	 */
	public static void setErrorLocal(Object... args){
		StringBuilder fileStr = new StringBuilder("");
		int i = 0;
		Object data = null;
		for(Object value : args){
			if(i == 0){
				data = value;
				i++;
				continue;
			}
			if(i == 2){
				setErrorType(value.toString());
				if(args.length > 3 && !args[3].equals("")){
					i++;
					continue;
				}
			}
			fileStr.append(value+" ");
            i++;
        }
		ValidResult dataTem = (ValidResult)data;
		dataTem.setSuccess(false);
		dataTem.setMsg(fileStr.toString());
		/*
		if(data instanceof JSONObject){
			JSONObject dataTem = (JSONObject)data;
			dataTem.put(VFT_ERROR_KEY, fileStr.toString());
		}else if(data instanceof Map){
			Map dataTem = (Map)data;
			dataTem.put(VFT_ERROR_KEY, fileStr.toString());
		}
		*/
		//setErrorStr(fileStr.toString());
	}

	/**
	 * 初始化配置文件
	 * @return 0 初始化正常 1初始化错误
	 */
	private int initParameter(){
		String encoding = "utf-8";
		StringBuilder fileStr = new StringBuilder("");
		try {
			File file = new File(URLDecoder.decode(this.getClass().getResource(JSONPATH).getFile(),"utf-8"));
			if(file.isFile() && file.exists()){
				InputStreamReader read = new InputStreamReader(
	            new FileInputStream(file),encoding);
				BufferedReader bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				while((lineTxt = bufferedReader.readLine()) != null){
					fileStr.append(lineTxt);
				}
				read.close();
				jsonObjectParm = JSONObject.fromObject(fileStr.toString());
				if(jsonObjectParm == null || (jsonObjectParm.size() == 0)){
					setError(VFT_ERROR_INIT, VFT_ERROR_FILECFGFORMAT);
					return 1;
				}
			}else{
				setError(VFT_ERROR_INIT, VFT_ERROR_FILECFGNOFIND);
				return 1;
			}
		} catch (IOException e) {
			setError(VFT_ERROR_INIT, VFT_ERROR_FILECFG);
			return 1;
		}
		return 0;
	}
	/**
	 * 验证数据接口支持JSONObject,Map
	 * @param modeStr 模板名称
	 * @param data 待验证数据
	 * @return 0 正常 除0之外都是错误
	 */
	public static ValidResult verificationApi(String modeStr, Object data){
		if(getErrorCode() == -1 || getErrorCode() != 0){
			CVerificationTool tem = new CVerificationTool();
			setErrorCode(tem.initParameter());
		}
		ValidResult ret = new ValidResult();
		if(data == null || ((JSONObject) data).size() == 0){
			setErrorLocal(ret, VFT_ERROR_ARGS_INIT, "Error");
			return ret;
		}
		if(getErrorCode() != 0){
			setErrorLocal(ret, VFT_ERROR_INIT, "Error");
			return ret;
		}
		if(jsonObjectParm.optString(modeStr).equals("")){
			setErrorLocal(ret, modeStr, VFT_ERROR_NOMODE);
			return ret;
		}
		String value = "";
		Iterator<?> it = jsonObjectParm.optJSONObject(modeStr).keys();
		while(it.hasNext()){
			String key = (String)it.next();
			value = verificationGetValue(data, key);
			if(value.trim().equals("")){
				if(jsonObjectParm.optJSONObject(modeStr).optJSONArray(key).opt(2).equals("NOTNULL")){
					setErrorLocal(ret, key, VFT_ERROR_NOTNULL, jsonObjectParm.optJSONObject(modeStr).optJSONArray(key).opt(1));
					return ret;
				}else{
					continue;
				}
			}
			if(verification(jsonObjectParm.optJSONObject(modeStr).optJSONArray(key), value, ret) != 0){
				return ret;
			}
		}
		ret.setSuccess(true);
		return ret;
	}
	/**
	 * 根据不同数据类型获取 KEY对应值
	 * @param data 待验证数据
	 * @param key  待验证数据的KEY
	 * @return String
	 */
	@SuppressWarnings("unchecked")
	private static String verificationGetValue(Object data, String key){
		if(data instanceof JSONObject){
			JSONObject dataTem = (JSONObject)data;
			return dataTem.optString(key);
		}else if(data instanceof Map){
			Map dataTem = (Map)data;
			if(dataTem.get(key) == null){
				return "";
			}else{
				return (String) dataTem.get(key);
			}
		}
		return "";
	}
	/**
	 * 验证数据
	 * @param rule 配置文件验证规则
	 * @param data 待验证数据的 VALUE
	 * @return 0 正常 1错误
	 */
	private static int verification(JSONArray rule, String data, Object inData){
		if(!rule.optString(6).equals("")){
			Pattern pattern = Pattern.compile(rule.optString(6));
			if(!pattern.matcher(data).matches()){
				setErrorLocal(inData, rule.optString(0), VFT_ERROR_PREG, rule.optString(1));
				return 1;
			}
		}
		if(rule.optString(3).equals("num")){
			if(!isInteger(data)){
				setErrorLocal(inData, rule.optString(0), VFT_ERROR_TYPE, rule.optString(1));
				return 1;
			}
		}
		int len = data.length();
		if(len < Integer.parseInt(rule.optString(4)) || len > Integer.parseInt(rule.optString(5))){
			setErrorLocal(inData, rule.optString(0), VFT_ERROR_LENGTH, rule.optString(1));
			return 1;
		}
		if(!rule.optString(7).equals("") && !rule.optString(8).equals("")){
			try {
				Integer flag = -1;
				Class<?> cls = Class.forName(rule.optString(7));
				Method method = cls.getMethod(rule.optString(8), String.class);
				flag = (Integer) method.invoke(cls.newInstance(), data);
				if(flag != 0){
					setErrorLocal(inData, rule.optString(0), VFT_ERROR_METHOD, rule.optString(1));
					return 1;
				}
			} catch (Exception e) {
				System.out.println(e);
				setErrorLocal(inData, rule.optString(0), VFT_ERROR_METHOD, rule.optString(1));
				return 1;
			}
		}
		return 0;
	}
	/**
	 * 转换字符串为数组去除前后空格
	 *@param Str
	 *@return jsonObject
	 */
	public static JSONObject StringToJsonObjectCV(String Str){
		JSONObject jsonObjectParm = JSONObject.fromObject(Str);
		if(jsonObjectParm == null || (jsonObjectParm.size() == 0)){
			setError(VFT_ERROR_INIT, VFT_ERROR_FILECFGFORMAT);
			return null;
		}
		Iterator<?> it = jsonObjectParm.keys();
		while(it.hasNext()){
			String key = (String)it.next();
			jsonObjectParm.put(key, jsonObjectParm.optString(key).trim());
		}
		return jsonObjectParm;
	}
	/**
	 * 判断是否是数字
	 * @param str
	 * @return 是整数返回true,否则返回false
	 */
	public static boolean isInteger(String str) {    
	    Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");    
	    return pattern.matcher(str).matches();    
	}

	public static boolean isMobileNO(String mobiles) {
		Pattern p = Pattern.compile("^((13[0-9])|(17[0-9])|(18[0-9])|(14[0-9])|(15[0-9])|(18[0-9]))\\d{8}$");
		Matcher m = p.matcher(mobiles);
		return m.matches();
	}

	public static boolean isMail(String email) {
		Pattern p = Pattern.compile("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");
		Matcher m = p.matcher(email);
		return m.matches();

	}
	/** 
	 * @param @param args    
	 * @return void    
	 * @throws IOException 
	 */
	public static void main(String[] args){
		String mobile = "17750409536";
		boolean result = CVerificationTool.isMobileNO(mobile);
		String mail = "792270107@.com";
		boolean ret = CVerificationTool.isMail(mail);
		JSONObject jsonObject = new JSONObject();
	    jsonObject.put("aaa", "ccc");
	    jsonObject.put("email", "cccqq.com");
	    jsonObject.put("iptype", "1");
	    System.out.println(CVerificationTool.verificationApi("data", jsonObject));
	    System.out.println(CVerificationTool.getErrorStr());
	    Map<String, String> map = new HashMap<String, String>();
	    map.put("name", "ccc");
	    map.put("pass", "cc1111111c");
	    map.put("aa", "ccc");
	    System.out.println(map.get("aa"));
	    System.out.println(CVerificationTool.verificationApi("user", map));
	    System.out.println(CVerificationTool.getErrorStr()+"ceshi");
	}

}
